前言

阅读本文,或者说本系列(编号B开头)前,建议先看一遍A00【科普】计算机网络概述 | Magiku’s药剂屋以了解一个大致的计算机网络体系。

在局域网中,当网络设备有数据要发送给另一台网络设备时,通常都是通过对方的ip地址进行通信。(即便是使用网址,其本质也是ip地址,我们之后会介绍DNS)

但是仅有IP地址是不够的,因为IP报文必须封装成数据帧才能通过物理网络发送,因此发送方还需要知道接收方的物理地址(即MAC地址)。

ARP协议即可以实现将IP地址解析为MAC地址,主机或三层网络设备上会维护一张ARP表,用于存储IP地址和MAC地址的关系。

而交换机则是根据数据帧的目标mac地址去转发给负责处理该数据帧的设备。

我们接下来会先介绍数据帧的结构,接着介绍交换机的工作原理,最后介绍ARP相关的知识点(包括ARP代理等)。

数据帧

MAC地址

MAC(Media Access Control)地址,也称物理地址;但严谨来讲,它并不是“地址”,而是“身份证”。

MAC地址由48bit长、12位的16进制数字组成,其中从左到右开始,0到23bit是厂商向IETF等机构申请用来标识厂商的代码,24到47bit由厂商自行分派,是各个厂商制造的所有网卡的一个唯一编号。

MAC地址可以分为3种类型:

  • 单播MAC地址:这种类型的MAC地址唯一的标识了以太网上的一个终端,该地址为全球唯一的硬件地址。
  • 广播MAC地址:全1的MAC地址(FF-FF-FF-FF-FF-FF),用来表示LAN上的所有终端设备。
  • 组播MAC地址:除广播地址外,第8bit为1的MAC地址为组播MAC地址(例如01-00-00-00-00-00),用来代表LAN上的一组终端。

数据报文的封装

许多新手第一次学习封装与解封装都有点似懂非懂,其实只要理解这项技术的目标、出发点就很好懂了。

网络通信的特点就是快速、量大。

数据报文的封装就是为了让每个节点都能快速的分辨这个数据报文要交给谁以及“我”需不需要进行处理

这就好比让员工带工牌/穿工服,园区保安只需要看一眼来访者的衣着就知道该不该放行,而不需要拦下来进行盘问检查身份。(这个比喻很粗略,不代表实际的设备针对数据报文的处理过程)

在计算机网络中,我们总会提到“源地址”与“目的地址”,中译中过来,就是“发件人”与“收件人”。

对于一台设备来说,它对外发送一个数据报文,则源地址是“我”,目的地址是“希望收到这个数据报文的人”

对于一台设备来说,它收到一个数据报文,则数据报文中的源地址是“发送这个数据包的人”;目的地址理论上是“我”,如果不是“我”,说明这个数据报文不是给“我”的。

数据帧的结构

常见的一种数据帧——Ethernet Ⅱ 格式:

目的MAC地址
(6字节)
源MAC地址
(6字节)
类型
(2字节)
数据内容
(46~1500字节)
CRC验证码
(2字节)
  1. 【目的MAC地址】是排在第一位,这很好理解,封装的目的就是为了快速实现数据报文的转发与处理。

    设备收到数据帧后,先看/先接收到【目的MAC地址】,发现【目的MAC地址】不是自己,或者该地址不是一个广播/组播地址,则可以直接丢弃该数据帧,不做处理。

  2. 【源MAC地】址排第二位,这是为了交换设备学习记录发送者在那里,同时对于终端设备来说,知道发送者是谁也很重要。

  3. 【类型】是指【数据内容】的类型,方便设备将【数据内容】交给对应的数据处理单元。(垃圾分类)

  4. 【CRC验证码】则是验证该数据帧是否完整,正因为检查是否完整需要完整接收读取该数据帧,因此CRC验证码就放置在最后一位。

实际的数据报文是多层封装,呈“套娃”结构,比如在后面介绍ARP时,以上的数据帧内的“数据内容”部分,就有一层ARP的报文结构。

交换机的工作原理

对于交换机来说,它的职责是为多台设备准确且尽量少占用资源地转发数据帧。

交换机内部会维护一张MAC地址映射表,用于记录一个MAC地址设备连接在哪个接口。

交换机对于数据帧的转发操作:

假设当前有一台刚启动的交换机,连接好设备后,设备A准备发送一个数据帧给B,这时对交换机来说:

  1. 它先接收到【目的MAC地址】,然后检查自己的MAC地址接口映射表,没找到该MAC地址(刚开机,MAC地址表为空)
  2. 接着收到了【源MAC地址】,就将A的该MAC地址记录到表中,并标注是哪个接口(从哪个接口收到的数据帧)
  3. 因为没有在MAC地址表中找到,因此当数据帧接收完毕后,交换机会将该数据帧从其余所有接口发送出去(这种操作称为”泛洪“),以免影响通信。

假设设备B收到经过交换机泛洪来的数据帧,”阅读“完毕,开始”回信“给设备A。

  1. 等交换机收到回来的数据帧,该数据帧的【目的MAC地址】为A,检查MAC地址表,发现有A的数据,就知道发送给哪个接口了。
  2. 接着收到【源MAC地址】,发现并记录下B的信息。

等设备A也“回信”给B:

  1. 交换机收到的新数据帧的【目的MAC地址】为B,检查MAC地址表,发现有B的数据,知道发送给哪个接口。

而如果交换机收到的数据帧中【目的MAC地址】是一个多播地址(广播/组播),则会向所有接口泛洪该数据帧。

如图为我在模拟器简单搭建的拓扑,以及显示的交换机mac地址表。

表项中还有“vlan”一列,有关vlan的知识请看B05【交换基础】vlan、接口类型、vlanif | Magiku’s药剂屋

ARP协议

基本原理

前面的小节中,我们分析数据帧在交换网络中的运动过程时,是特别假定源计算机已经知道了目的计算机的 MAC 地址。

事实上,一个源设备开始是不知道目的设备的 MAC地址的。

源设备总是通过某种机制(例如DNS)先获取到目的设备的IP地址,然后利用ARP协议对此IP地址进行解析,从而获取到目的设备的MAC地址。

源设备需要解析一个 IP 地址时,会发出一个广播帧,广播帧的载荷数据是一个ARP 请求报文。

目的设备在接收到 ARP 请求报文后,会向源设备发送一个单播帧,该单播帧的载荷数据是一个ARP应答报文,该ARP应答报文中包含了目的设备的MAC 地址。

ARP表、类型、静态绑定

如果每次PC1访问PC2都要进行ARP广播请求MAC地址,这影响通信速度,也占用网络资源。

因此设备都会维护一张ARP表,用于记录一些ARP记录,无需每次都去请求MAC地址。

在Windows电脑上,我们可以输入ARP -A,显示当前设备的ARP表。

1
2
3
4
5
6
7
8
9
10
11
C:\Users\magiku>arp -a

接口: 192.168.235.103 --- 0xa
Internet 地址 物理地址 类型
192.168.235.91 ce-4f-a9-42-59-be 动态
192.168.235.255 ff-ff-ff-ff-ff-ff 静态
224.0.0.22 01-00-5e-00-00-16 静态
224.0.0.251 01-00-5e-00-00-fb 静态
224.0.0.252 01-00-5e-00-00-fc 静态
239.255.255.250 01-00-5e-7f-ff-fa 静态
255.255.255.255 ff-ff-ff-ff-ff-ff 静态

可以看到类型分[动态]与[静态]:

  • 动态ARP表项由ARP协议通过ARP报文自动生成和维护,有时间限制,可以被新的ARP报文更新,也可以被静态ARP表项覆盖。
  • 静态ARP表项是由网络管理员手工建立的IP地址和MAC地址之间固定的映射关系。静态ARP表项是长期存在,不会被动态ARP表项覆盖。

广播地址、组播地址则是设备配根据自己本身的信息生成的,也是属于长期存在的,因此也是静态。

在Windows电脑上,有关ARP的命令如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
C:\Users\magiku>arp /?

显示和修改地址解析协议(ARP)使用的“IP 到物理”地址转换表。

ARP -s inet_addr eth_addr [if_addr]
ARP -d inet_addr [if_addr]
ARP -a [inet_addr] [-N if_addr] [-v]

-a 通过询问当前协议数据,显示当前 ARP 项。
如果指定 inet_addr,则只显示指定计算机
的 IP 地址和物理地址。如果不止一个网络
接口使用 ARP,则显示每个 ARP 表的项。
-g 与 -a 相同。
-v 在详细模式下显示当前 ARP 项。所有无效项
和环回接口上的项都将显示。
inet_addr 指定 Internet 地址。
-N if_addr 显示 if_addr 指定的网络接口的 ARP 项。
-d 删除 inet_addr 指定的主机。inet_addr 可
以是通配符 *,以删除所有主机。
-s 添加主机并且将 Internet 地址 inet_addr
与物理地址 eth_addr 相关联。物理地址是用
连字符分隔的 6 个十六进制字节。该项是永久的。
eth_addr 指定物理地址。
if_addr 如果存在,此项指定地址转换表应修改的接口
的 Internet 地址。如果不存在,则使用第一
个适用的接口。
示例:
> arp -s 157.55.85.212 00-aa-00-62-c6-09.... 添加静态项。
> arp -a .... 显示 ARP 表。

实际现网中,我们总会遇到IP冲突的情况,如果设备因需求不能修改ip地址,就可以通过添加静态表项,绑定IP地址与MAC地址,保障临时的网络通信需求。

另外静态绑定ARP,也是一种安全保护措施,避免ARP欺骗以及避免出现ip冲突的假网关影响通信。

ARP报文格式

一个完整的ARP数据帧,包含基础的以太网帧结构,ARP的报文内容是在以太网帧的[数据内容]中。

设备收到一个数据帧,通过协议类型了解到[数据内容]为ARP报文后,就将该数据帧中的ARP报文上交给设备的ARP协议模块去处理。(这个过程就叫解封装)

完整数据帧的以太网首部:

字段 长度 含义
以太网目的MAC 48比特 以太网目的MAC地址。发送ARP请求报文时,该字段为广播的MAC地址0xffff-ffff-ffff。
以太网源MAC 48比特 以太网源MAC地址。
帧类型 16比特 数据的类型。对于ARP请求或应答来说,该字段的值为0x0806。

ARP报文:

字段 长度 含义
硬件类型 16比特 硬件地址的类型。对于以太网,该字段的值为1。
协议类型 16比特 发送方要映射的协议地址类型。对于IP地址,该字段的值为0x0800。
硬件地址长度 8比特 硬件地址的长度。对于ARP请求或应答来说,该字段值为6。
协议地址长度 8比特 协议地址的长度。对于ARP请求或应答来说,该字段值为4。
OP 16比特 操作类型。OP的值与操作类型的关系如下:1表示ARP请求报文。2表示ARP应答报文。
源MAC 48比特 源MAC地址。
源IP 32比特 源IP地址。
目的MAC 48比特 目的MAC地址。发送ARP请求报文时,该字段为全0的MAC地址0x0000-0000-0000。(ARP是为了请求MAC地址,所以不知道目的MAC,值就为0)
目的IP 32比特 目的IP地址。(接收端根据该ip地址,判断该ARP报文是不是发给自己的,是不是要请求我的MAC地址)

免费ARP

免费ARP实际上是一个人为的称呼,用于描述该特定的ARP行为。

实际上,在ARP报文中并没有一个专门的字段或类型称为“免费 ARP”。ARP报文主要包括ARP请求和ARP应答两种类型。

设备发送ARP请求,以确定是否有其他设备使用了该 IP 地址。(报文中源IP和目的IP都是发送方自己的IP)

如果没有其他设备响应该ARP请求,那么设备可以确认该IP地址是空闲的。

“欸、这有个IP地址,是谁的,有没有人用啊。没人的话,俺可拿去用了”

免费ARP有如下作用:

  • IP地址冲突检测:当设备更换了一个IP地址(包括自动获取的IP)或者接口状态变为Up时,设备主动对外发送免费ARP报文。

    正常情况下不会收到ARP应答,如果收到,则表明本网络中存在与自身IP地址重复的地址。

    如果检测到IP地址冲突,那么设备就暂时不使用该IP地址(没有其他IP的话,临时使用169.254.X.X);

    同时设备会周期性的广播发送免费ARP请求报文,直到冲突解除(没有再收到ARP应答)。

  • 通告一个新的MAC地址:如果发送方更换了网卡,MAC地址变化了,为了能够在动态ARP表项超时老化前通告网络中其他设备,发送方可以发送一个免费ARP。

  • 在VRRP备份组中用来通告主备发生变换:发生主备变换后,MASTER设备会广播发送一个免费ARP报文来通告发生了主备变换。

设备收到一个我们称为免费ARP的ARP请求后,进行如下判断:

设备通过发现报文中源IP和目的IP是一样的,知道该ARP请求报文是一个免费ARP。

  • 如果免费ARP报文中源IP地址和自己的IP地址相同,则回复ARP应答报文,相当于告知此IP地址在网络中存在冲突。
  • 如果免费ARP报文中源IP地址和自己的IP地址不同,并且设备上已经有免费ARP报文中源IP地址对应的动态ARP表项,则根据收到的免费ARP报文更新该ARP表项。

ARP代理

ARP是二层技术,作用在数据帧上,无法跨越网段进行传输;更准确一下,ARP是通过二层广播帧进行交互的,只能在一个广播域内传输,无法跨越到另一个广播域。

而ARP代理就是让网关设备代理去另一个广播域发送ARP请求,并且代理后续的数据通信。

本文接下来的内容会包含子网、路由等技术,可以先在科普篇学习相关知识后再继续。

A00【科普】计算机网络概述 | Magiku’s药剂屋

在路由器上的应用

如图,路由器R1下连接了两台设备PC1与PC2:

  • 对R1来说,其接口1配置的网段为10.1.1.0 /24,接口2配置的网段为10.1.2.0 /24,这是两个不同的网段。

  • 对PC1来说,其配置的网段为10.1.0.0 /16;对PC2来说,其配置的网段为10.1.0.0 /16,这是同一个网段。

  • 这种拓扑场景就是在R1上进行了子网划分,但出于某些情况,PC1与PC2的子网掩码保持原有。

在 PC1上进行 ping 测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
PC>ping 10.1.1.254

Ping 10.1.1.254: 32 data bytes, Press Ctrl_C to break
From 10.1.1.254: bytes=32 seq=1 ttl=255 time=16 ms
From 10.1.1.254: bytes=32 seq=2 ttl=255 time=15 ms
From 10.1.1.254: bytes=32 seq=3 ttl=255 time<1 ms
From 10.1.1.254: bytes=32 seq=4 ttl=255 time=16 ms
From 10.1.1.254: bytes=32 seq=5 ttl=255 time=15 ms

--- 10.1.1.254 ping statistics ---
5 packet(s) transmitted
5 packet(s) received
0.00% packet loss
round-trip min/avg/max = 0/12/16 ms

PC>ping 10.1.2.2

Ping 10.1.2.2: 32 data bytes, Press Ctrl_C to break
From 10.1.1.1: Destination host unreachable
From 10.1.1.1: Destination host unreachable
From 10.1.1.1: Destination host unreachable
From 10.1.1.1: Destination host unreachable
From 10.1.1.1: Destination host unreachable

--- 10.1.2.2 ping statistics ---
5 packet(s) transmitted
0 packet(s) received
100.00% packet loss

可以发现,PC1能访问R1,却无法访问PC2。

这是因为对R1来说,10.1.1.1与10.1.2.2这两个IP地址匹配出来是两个IP地址。

而网段的划分就是隔离广播域的,因此PC1发送的ARP请求会被R1拦截,不传递到PC2所在的网段中。

为此,我们就需要在R1的接口1上启用代理ARP功能:

1
2
[R1]interface g0/0/1
[R1-GigabitEthernet0/0/1]arp-proxy enable

这时再去测试,就可以发现 PC1能 ping 通 PC2了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
PC>ping 10.1.2.2

Ping 10.1.2.2: 32 data bytes, Press Ctrl_C to break
From 10.1.2.2: bytes=32 seq=1 ttl=127 time=16 ms
From 10.1.2.2: bytes=32 seq=2 ttl=127 time=15 ms
From 10.1.2.2: bytes=32 seq=3 ttl=127 time<1 ms
From 10.1.2.2: bytes=32 seq=4 ttl=127 time<1 ms
From 10.1.2.2: bytes=32 seq=5 ttl=127 time=16 ms

--- 10.1.2.2 ping statistics ---
5 packet(s) transmitted
5 packet(s) received
0.00% packet loss
round-trip min/avg/max = 0/9/16 ms

并且ARP表项内,显示的是R1的MAC地址(R1代理了PC2,相当于套了PC2的ip地址的“皮”)

注意事项

开启ARP代理的路由器会严格匹配网段

ARP请求报文内的[目标IP地址]如果不符合接口所处的网段,那么路由器不会从该接口转发这个ARP请求报文。

比如,前面的这张拓扑图:

如果PC2的ip地址不是10.1.2.2,而是10.1.1.2,那么即使配置了ARP代理,PC1还是ping不通PC2。

对路由器来说,它会“带脑子”的帮忙传:

如果你是要找10.1.2.2,那我的g0/0/0口就是10.1.2.0 /24网段,所以我帮你传过去。

如果你是要找10.1.1.2,那我的g0/0/1口就是10.1.1.0 /24网段,可我就是在这个接口收到的,那我没必要管,也不会转到g0/0/1口。

要求互通的话,接口必须都配置代理

继续以前面的拓扑为例,我们只要接口1配置了ARP代理,结果PC1可以ping通PC2,这没问题。

但PC2是无法ping通PC2的,因为没在接口2配置ARP代理,路由器R1不会去转发PC2的ARP请求。

对于路由器来说,注意检查是否开启了ARP功能

如果两台设备上互连的接口,配置IP地址后发现两者无法Ping通。

请确认接口下是否已经配置了arp broadcast enable命令,如果没有配置该命令,接口不会主动发送ARP请求报文,导致无法主动学习ARP,获得ARP表项。

华为设备的arp broadcast enable命令在V200R003C00及之前版本默认处于未启用状态,在V200R003C01版本之后默认处于启用状态。